<template>
  <div class="pic-zoom">
    <!-- https://res.mutouyun.com/upload/product/20200512/n8AhSxKtWF.png -->
    <div class="small-box" @mouseenter="handEnter" @mousemove="handMove" @mouseout="handOut">
      <img :src="src" alt="">
      <div class="mask-slide" v-show="showMagnifier" :style="{width:maskSlide.maskWidth + 'px',
      height:maskSlide.maskHeight + 'px',
      top:transformMask.top + 'px',
      left:transformMask.left + 'px',}"></div>
    </div>
    <div class="magnifier" v-show="showMagnifier" :style="{width:configs.width + 'px',
    height:configs.height + 'px',
    backgroundSize: `${configs.width * configs.scale}px ${configs.height * configs.scale}px`,
    backgroundImage: `url(${src})`,
    backgroundPosition: `${bigImgMove.left}px ${bigImgMove.top}px`,
    }">
    </div>
  </div>
</template>
<script>
export default {
  props: {
    src: {
      type: String
    },
    configs: {
      type: Object,
      default() {
        return {
          width: 400,
          height: 400,
          scale: 4
        };
      }
    }
  },
  data() {
    return {
      imgObj: {},
      transformMask: {
        top: 0,
        left: 0
      },
      maskSlide: {
        maskWidth: 0,
        maskHeight: 0
      },
      bigImgMove: {
        top: 0,
        left: 0
      },
      showMagnifier: false
    };
  },
  computed: {
    
  },
  methods: {
    handEnter(e) {
      this.imgObj = this.$el.getElementsByClassName("small-box")[0];
      // 动态获取小图的位置（或者监听 scroll ）
      let imgRectNow = this.imgObj.getBoundingClientRect();
      let objX = e.clientX - imgRectNow.left;
      let objY = e.clientY - imgRectNow.top;

      // 计划滑块高宽
      this.maskSlide = {
        maskWidth:
          this.imgObj.getBoundingClientRect().width / this.configs.scale,
        maskHeight:
          this.imgObj.getBoundingClientRect().height / this.configs.scale
      };

      // 计算初始的遮罩左上角的坐标
      let maskX = objX - this.maskSlide.maskWidth / 2;
      let maskY = objY - this.maskSlide.maskHeight / 2;
      // 判断是否超出界限,并纠正
      maskY = maskY < 0 ? 0 : maskY;
      maskX = maskX < 0 ? 0 : maskX;
      if (maskY + this.maskSlide.maskHeight >= imgRectNow.height) {
        maskY = imgRectNow.height - this.maskSlide.maskHeight;
      }
      if (maskX + this.maskSlide.maskWidth / 2 >= imgRectNow.width) {
        maskX = imgRectNow.width - this.maskSlide.maskWidth;
      }
      this.transformMask = {
        top: maskY,
        left: maskX
      };
      this.showMagnifier = true;
    },
    handMove(e) {
      let imgRectNow = this.imgObj.getBoundingClientRect();
      // 计算初始的遮罩左上角的坐标
      let objX = e.clientX - imgRectNow.left;
      let objY = e.clientY - imgRectNow.top;

      // 计算初始的遮罩左上角的坐标
      let maskX = objX - this.maskSlide.maskWidth / 2;
      let maskY = objY - this.maskSlide.maskHeight / 2;

      // 判断是否超出界限,并纠正
      maskY = maskY < 0 ? 0 : maskY;
      maskX = maskX < 0 ? 0 : maskX;
      if (maskY + this.maskSlide.maskHeight >= imgRectNow.height) {
        maskY = imgRectNow.height - this.maskSlide.maskHeight;
      }
      if (maskX + this.maskSlide.maskWidth >= imgRectNow.width) {
        maskX = imgRectNow.width - this.maskSlide.maskWidth;
      }

      // 遮罩移动
      this.transformMask = {
        top: maskY,
        left: maskX
      };
      //计算图片
      this.bigImgMove = {
        left:
          -maskX *
          ((this.configs.scale * this.configs.width) / imgRectNow.width),
        top:
          -maskY *
          ((this.configs.scale * this.configs.height) / imgRectNow.height)
      };
    },
    handOut() {
      this.showMagnifier = false;
    }
  }
};
</script>
<style lang="scss" scoped>
.pic-zoom {
  width: 100%;
  height: 100%;
  position: relative;
  .magnifier {
    position: absolute;
    left: 105%;
    top: 0;
    background-repeat: no-repeat;
    background-color:#fff;
    z-index:999;
    img {
      width: 100%;
      height: 100%;
    }
  }
}
.small-box {
  width: 100%;
  height: 100%;
  position: relative;
  img {
    width: 100%;
    height: 100%;
  }
  .mask-slide {
    background: rgba(0, 0, 0, 0.4);
    position: absolute;
    top: 50px;
    left: 50px;
    pointer-events: none;
  }
}
</style>
